﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Linq.Expressions;

namespace EmbeddedLanguage
{
    public class CompiledExpressionCache_0x0<TMe>
    {
        [ThreadStatic]
        private static Dictionary<Expression<Action<TMe>>, Action<TMe>> Cache;

        private static Dictionary<Expression<Action<TMe>>, Action<TMe>> CacheNN
        {
            get
            {
                if (Cache == null) Cache = new Dictionary<Expression<Action<TMe>>, Action<TMe>>();
                return Cache;
            }
        }

        public static Action<TMe> GetCompiledAction(Expression<Action<TMe>> expr)
        {
            if (!CacheNN.ContainsKey(expr))
            {
                CacheNN[expr] = expr.Compile();
            }
            return CacheNN[expr];
        }
    }

    public class CompiledExpressionCache_0x1<TMe, TOut>
    {
        [ThreadStatic]
        private static Dictionary<Expression<Func<TMe, TOut>>, Func<TMe, TOut>> Cache;

        private static Dictionary<Expression<Func<TMe, TOut>>, Func<TMe, TOut>> CacheNN
        {
            get
            {
                if (Cache == null) Cache = new Dictionary<Expression<Func<TMe, TOut>>, Func<TMe, TOut>>();
                return Cache;
            }
        }

        public static Func<TMe, TOut> GetCompiledFunc(Expression<Func<TMe, TOut>> expr)
        {
            if (!CacheNN.ContainsKey(expr))
            {
                CacheNN[expr] = expr.Compile();
            }
            return CacheNN[expr];
        }
    }

    public class CompiledExpressionCache_1x1<TMe, TInput1, TOut>
    {
        [ThreadStatic]
        private static Dictionary<Expression<Func<TMe, TInput1, TOut>>, Func<TMe, TInput1, TOut>> Cache;

        private static Dictionary<Expression<Func<TMe, TInput1, TOut>>, Func<TMe, TInput1, TOut>> CacheNN
        {
            get
            {
                if (Cache == null) Cache = new Dictionary<Expression<Func<TMe, TInput1, TOut>>, Func<TMe, TInput1, TOut>>();
                return Cache;
            }
        }

        public static Func<TMe, TInput1, TOut> GetCompiledFunc(Expression<Func<TMe, TInput1, TOut>> expr){
            if (!CacheNN.ContainsKey(expr))
            {
                CacheNN[expr] = expr.Compile();
            }
            return CacheNN[expr];
        }
    }

    
}
